package com.mixes.logic;

import static com.mixes.field.TwitterField.*;
import static com.mixes.util.Utility.*;

import java.util.HashMap;
import java.util.LinkedList;

import twitter4j.Paging;
import twitter4j.ResponseList;
import twitter4j.Status;
import twitter4j.StatusUpdate;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.auth.AccessToken;
import twitter4j.auth.RequestToken;
import android.app.Activity;
import android.os.Handler;

import com.mixes.field.IField;
import com.mixes.util.PreferencesUtils;
import com.mixes.view.TwitterLoginDialog;
import com.mixes.view.TwitterLoginDialog.OnWebListener;

/**
 * TODO Auto-generated constructor stub
 * @author Author:
 * @version Revision:
 */
public class TwitterLogic extends ALogic {
    private static TwitterLogic sTwitterLogic;

    private Activity mActivity;

    private String mConsumerKey;

    private String mConsumerSecret;

    private String mCallbackUrl;

    private static final String KEY_ACCESS_TOKEN = "KEY_ACCESS_TOKEN";

    private static final String KEY_ACCESS_VERIFIER = "KEY_ACCESS_VERIFIER";

    private Twitter mTwitter;

    private RequestToken mRequestToken;

    private AccessToken mAccessToken;

    private Handler mHandler;

    private TwitterLoginDialog mLoginDialog;

    private static final int MAX_LIST_COUNT = 200;

    /**
     * TODO Auto-generated constructor stub
     */
    public TwitterLogic(Activity activity, String callbackUrl, String consumerKey, String consumerSecret) {
        mActivity = activity;
        mHandler = new Handler();

        mCallbackUrl = callbackUrl;
        mConsumerKey = consumerKey;
        mConsumerSecret = consumerSecret;
        mTwitter = new TwitterFactory().getInstance();
        mTwitter.setOAuthConsumer(mConsumerKey, mConsumerSecret);
    }

    public static TwitterLogic getInstance(Activity activity, String callbackUrl, String consumerKey, String consumerSecret) {
        if (sTwitterLogic == null) {
            sTwitterLogic = new TwitterLogic(activity, callbackUrl, consumerKey, consumerSecret);
        }
        return sTwitterLogic;
    }

    public void authorize(OnAuthorizeListener onAuthorizeListener) {
        mOnAuthorizeListener = onAuthorizeListener;

        if (mOnAuthorizeListener != null) {
            mOnAuthorizeListener.onStart();
        }
        if (isLogined()) {
            mAccessToken = new AccessToken(getAccessToken(), getAccessVerifier());
            mTwitter.setOAuthAccessToken(mAccessToken);
            if (mOnAuthorizeListener != null) {
                mOnAuthorizeListener.onComplete();
            }
        } else {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        mRequestToken = mTwitter.getOAuthRequestToken();
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                mLoginDialog = new TwitterLoginDialog(mActivity);
                                mLoginDialog.setOnWebListener(new OnWebListener() {
                                    @Override
                                    public void onGetParameter(final String... urls) {
                                        Thread thread = new Thread(new Runnable() {
                                            @Override
                                            public void run() {
                                                try {
                                                    AccessToken accessToken = mTwitter.getOAuthAccessToken(mRequestToken, urls[0]);
                                                    setAccessToken(accessToken.getToken());
                                                    setAccessVerifier(accessToken.getTokenSecret());
                                                    mHandler.post(new Runnable() {
                                                        @Override
                                                        public void run() {
                                                            if (mOnAuthorizeListener != null) {
                                                                mOnAuthorizeListener.onComplete();
                                                            }
                                                        }
                                                    });
                                                } catch (final TwitterException e) {
                                                    mHandler.post(new Runnable() {
                                                        @Override
                                                        public void run() {
                                                            if (mOnAuthorizeListener != null) {
                                                                mOnAuthorizeListener.onFailed(e);
                                                            }
                                                        }
                                                    });
                                                }
                                            }
                                        });
                                        thread.start();
                                    }
                                });
                                mLoginDialog.loadUrl(mRequestToken.getAuthorizationURL());
                                mLoginDialog.show();
                            }
                        });
                    } catch (final TwitterException e) {
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                if (mOnAuthorizeListener != null) {
                                    mOnAuthorizeListener.onFailed(e);
                                }
                            }
                        });
                    }
                }
            });
            thread.start();
        }
    }

    private boolean isLogined() {
        if (!isEmpty(getAccessToken()) && !isEmpty(getAccessVerifier())) {
            return true;
        }
        return false;
    }

    private void setAccessToken(String accessToken) {
        PreferencesUtils.setPreferences(mActivity, KEY_ACCESS_TOKEN, accessToken);
    }

    private void setAccessVerifier(String accessVerifier) {
        PreferencesUtils.setPreferences(mActivity, KEY_ACCESS_VERIFIER, accessVerifier);
    }

    private String getAccessToken() {
        return PreferencesUtils.getPreferences(mActivity, KEY_ACCESS_TOKEN, null);
    }

    private String getAccessVerifier() {
        return PreferencesUtils.getPreferences(mActivity, KEY_ACCESS_VERIFIER, null);
    }

    public void prepareTimeLine(OnTimeLineListener onTimeLineListener) {
        mOnTimeLineListener = onTimeLineListener;

        if (mOnTimeLineListener != null) {
            mOnTimeLineListener.onStart();
        }

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                final LinkedList<HashMap<IField, Object>> timeLineList = new LinkedList<HashMap<IField, Object>>();
                Paging paging = new Paging(MAX_LIST_COUNT);
                try {
                    // ResponseList<Status> timeLine = mTwitter.getHomeTimeline(paging);
                    ResponseList<Status> timeLine = mTwitter.getHomeTimeline();
                    HashMap<IField, Object> timeLineMap;
                    for (Status status : timeLine) {
                        timeLineMap = new HashMap<IField, Object>();
                        timeLineMap.put(profileImageUrl, status.getUser().getProfileImageURL());
                        timeLineMap.put(name, status.getUser().getName());
                        timeLineMap.put(screenName, status.getUser().getScreenName());
                        timeLineMap.put(createdAt, status.getCreatedAt());
                        timeLineMap.put(tweet, status.getText());
                        timeLineMap.put(test, status.getUser());
                        timeLineList.add(timeLineMap);
                    }
                    if (!isEmpty(timeLineList)) {
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                if (mOnTimeLineListener != null) {
                                    mOnTimeLineListener.onComplete(timeLineList);
                                }
                            }
                        });
                    } else {
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                if (mOnTimeLineListener != null) {
                                    mOnTimeLineListener.onFailed(new NullPointerException());
                                }
                            }
                        });
                    }
                } catch (final TwitterException e) {
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            if (mOnTimeLineListener != null) {
                                mOnTimeLineListener.onFailed(e);
                            }
                        }
                    });
                }
            }
        });
        thread.start();
    }

    public void send(final String text, OnSendListener onSendListener) {
        mOnSendListener = onSendListener;
        if (mOnSendListener != null) {
            mOnSendListener.onStart();
        }
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                StatusUpdate statusUpdate = new StatusUpdate(text);
                try {
                    mTwitter.updateStatus(statusUpdate);
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            if (mOnSendListener != null) {
                                mOnSendListener.onComplete();
                            }
                        }
                    });
                } catch (TwitterException e) {
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            if (mOnSendListener != null) {
                                mOnSendListener.onFailed();
                            }
                        }
                    });
                }
            }
        });
        thread.start();
    }
}
